package com.fgtit.fpcore;

import android.os.Handler;

import com.jason.fingerprint.AppContext;
import com.jason.fingerprint.beans.ui.FingerPrintBean;
import com.jason.fingerprint.listener.OnFingerPrintListener;
import com.jason.fingerprint.utils.EncoderUtils;

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import android_serialport_api.AsyncFingerprint;
import android_serialport_api.SerialPortManager;
import rx.Observable;
import rx.Observer;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

/**
 * @Description: 指纹管理模块
 * @Author: Jason Zhang
 * @Date: 2016/10/8 0008
 */
public class FPManager {

    private static final String TAG = FPManager.class.getSimpleName();

    public enum Type {
        REGISTER,   //指纹采集
        VALIDATE    //指纹验证
    }

    private static FPManager instance = new FPManager();

    private AsyncFingerprint registerFingerprint;//指纹采集
    private AsyncFingerprint validateFingerprint;//指纹验证

    private OnFingerPrintListener onFingerPrintListener;//指纹采集或者验证结果监听

    private static boolean isRunning = false;

    private static int mRegisterCount = 1;

    private int mScore = 0;

    public static FPManager getInstance() {
        return instance;
    }

    //开始采集或者验证
    public void execute(Type type, OnFingerPrintListener onFingerPrintListener) {
        this.onFingerPrintListener = onFingerPrintListener;
        isRunning = true;
        initData(type);
        onFingerPrintListener.onStart();
        mRegisterCount = 1;
        android.util.Log.i(TAG, "type:" + type);
        if (type == Type.REGISTER) {
            registerFingerprint.FP_GetImage();
        } else {
            if (AppContext.getInstance().is3GEquipment()) {
                validateFingerprint.FP_GetImage();
            } else {
                validateFingerprint.FP_GetImageEx();
            }
        }
    }

    //打开
    private Timer xTimer=null;
    private TimerTask xTask=null;
    private Handler xHandler;

    //开始打卡
    public void xTimerStart() {
        xTimer.schedule(xTask, 1000, 500);
    }

    //关闭指纹模块
    public void destory() {
        SerialPortManager.getInstance().closeSerialPort();
    }

    public void stopRunning() {
        isRunning = false;
    }

    private FPManager() {
        try {
            int code = FPMatch.getInstance().InitMatch(1, "http://www.hfcctv.com/");
            if (code == 0) {
                android.util.Log.i(TAG, "Init Match Error");
            } else {
                android.util.Log.i(TAG, "Init Match Success");
            }
        } catch (Exception e) {
            e.printStackTrace();
            android.util.Log.e(TAG, "Init Match Error", e);
        }
    }

    private void initData(Type type) {
        if (type == Type.REGISTER) {
            registerFingerprint = SerialPortManager.getInstance().getNewAsyncFingerprint();
            if (!SerialPortManager.getInstance().isOpen()) {
                android.util.Log.i(TAG, "isRunning: " + isRunning);
                android.util.Log.i(TAG, "Open Error ");
                if (isRunning) {
                    onFingerPrintListener.onFailed();
                }
                return;
            } else {
                android.util.Log.i(TAG, "is Open: ");
            }
//        registerFingerprint = SerialPortManager.getInstance().getNewAsyncFingerprint();
//        validateFingerprint = SerialPortManager.getInstance().getNewAsyncFingerprint();

            registerFingerprint.setOnGetImageListener(new AsyncFingerprint.OnGetImageListener() {
                @Override
                public void onGetImageSuccess() {
                    android.util.Log.i(TAG, "onGetImageSuccess mRegisterCount: " + mRegisterCount + ",isRunning:" + isRunning + ",showImage:" + onFingerPrintListener.showImage());
                    if (mRegisterCount == 1) {
                        if (isRunning) {
                            onFingerPrintListener.onLoading();
                        }
                    }
                    if (onFingerPrintListener.showImage()) {
                        registerFingerprint.FP_UpImage();
                    } else {
                        registerFingerprint.FP_GenChar(mRegisterCount);
                    }
                }

                @Override
                public void onGetImageFail() {
                    android.util.Log.i(TAG, "onGetImageFail isRunning: " + isRunning);
                    if (isRunning) {
                        registerFingerprint.FP_GetImage();
                    }
                }
            });

            registerFingerprint.setOnUpImageListener(new AsyncFingerprint.OnUpImageListener() {
                @Override
                public void onUpImageSuccess(byte[] data) {
                    android.util.Log.i(TAG, "onUpImageSuccess isRunning: " + isRunning);
//                Bitmap image = BitmapFactory.decodeByteArray(data, 0,data.length);
//                fingerprintImage.setBackgroundDrawable(new BitmapDrawable(image));
                    if (isRunning) {
                        registerFingerprint.FP_GenChar(mRegisterCount);
                        onFingerPrintListener.onImageSuccess(data);
                    }
                }

                @Override
                public void onUpImageFail() {
                    android.util.Log.i(TAG, "onUpImageFail isRunning: " + isRunning);
                    if (isRunning) {
                        onFingerPrintListener.onFailed();
                    }
                }
            });

            registerFingerprint.setOnGenCharListener(new AsyncFingerprint.OnGenCharListener() {
                @Override
                public void onGenCharSuccess(int bufferId) {
                    android.util.Log.i(TAG, "onGenCharSuccess isRunning: " + isRunning + ",bufferId:" + bufferId);
                    if (isRunning) {
                        if (bufferId == 1) {
                            registerFingerprint.FP_GetImage();
                            mRegisterCount++;
                        } else if (bufferId == 2) {
                            registerFingerprint.FP_RegModel();
                        }
                    }
                }

                @Override
                public void onGenCharFail() {
                    android.util.Log.i(TAG, "onGenCharFail isRunning: " + isRunning);
                    if (isRunning) {
                        onFingerPrintListener.onFailed();
                    }
                }
            });

            registerFingerprint.setOnRegModelListener(new AsyncFingerprint.OnRegModelListener() {

                @Override
                public void onRegModelSuccess() {
                    android.util.Log.i(TAG, "onRegModelSuccess isRunning: " + isRunning);
                    if (isRunning) {
                        registerFingerprint.FP_UpChar();
                    }
                }

                @Override
                public void onRegModelFail() {
                    android.util.Log.i(TAG, "onRegModelFail isRunning: " + isRunning);
                    if (isRunning) {
                        onFingerPrintListener.onFailed();
                    }
                }
            });

            registerFingerprint.setOnUpCharListener(new AsyncFingerprint.OnUpCharListener() {
                @Override
                public void onUpCharSuccess(byte[] model) {
                    android.util.Log.i(TAG, "onUpCharSuccess isRunning: " + isRunning);
                    //System.arraycopy(model, 0, mRefList[mRefCount],0, model.length);
                    if (isRunning) {
                        byte[] b = new byte[512];
                        System.arraycopy(model, 0, b, 0, 512);
                        onFingerPrintListener.onRegisterSuccess(b);
                    }
                }

                @Override
                public void onUpCharFail() {
                    android.util.Log.i(TAG, "onUpCharFail isRunning: " + isRunning);
                    if (isRunning) {
                        onFingerPrintListener.onFailed();
                    }
                }
            });
        } else {
            validateFingerprint = SerialPortManager.getInstance().getNewAsyncFingerprint();
            if (AppContext.getInstance().is3GEquipment()) {
                validateFingerprint.setOnGetImageListener(new AsyncFingerprint.OnGetImageListener() {
                    @Override
                    public void onGetImageSuccess() {
                        if (isRunning) {
                            onFingerPrintListener.onLoading();
                            if (onFingerPrintListener.showImage()) {
                                validateFingerprint.FP_UpImage();
                            } else {
                                validateFingerprint.FP_GenChar(1);
                            }
                        }
                    }

                    @Override
                    public void onGetImageFail() {
                        if (isRunning) {
                            validateFingerprint.FP_GetImage();
                        }
                    }
                });

                validateFingerprint.setOnUpImageListener(new AsyncFingerprint.OnUpImageListener() {
                    @Override
                    public void onUpImageSuccess(byte[] data) {
                        if (isRunning) {
                            onFingerPrintListener.onImageSuccess(data);
                            validateFingerprint.FP_GenChar(1);
                        }
                    }

                    @Override
                    public void onUpImageFail() {
                        if (isRunning) {
                            onFingerPrintListener.onFailed();
                        }
                    }
                });

                validateFingerprint.setOnGenCharListener(new AsyncFingerprint.OnGenCharListener() {
                    @Override
                    public void onGenCharSuccess(int bufferId) {
                        if (isRunning) {
                            validateFingerprint.FP_UpChar();
                        }
                    }

                    @Override
                    public void onGenCharFail() {
                        if (isRunning) {
                            onFingerPrintListener.onFailed();
                        }
                    }
                });

            } else {
                validateFingerprint.setOnGetImageExListener(new AsyncFingerprint.OnGetImageExListener() {
                    @Override
                    public void onGetImageExSuccess() {
                        if (isRunning) {
                            onFingerPrintListener.onLoading();
                            if (onFingerPrintListener.showImage()) {
                                validateFingerprint.FP_UpImageEx();
                            } else {
                                validateFingerprint.FP_GenCharEx(1);
                            }
                        }
                    }

                    @Override
                    public void onGetImageExFail() {
                        if (isRunning) {
                            validateFingerprint.FP_GetImageEx();
                        }
                    }

                });

                validateFingerprint.setOnUpImageExListener(new AsyncFingerprint.OnUpImageExListener() {
                    @Override
                    public void onUpImageExSuccess(byte[] data) {
                        if (isRunning) {
                            onFingerPrintListener.onImageSuccess(data);
                            validateFingerprint.FP_GenCharEx(1);
                        }
                    }

                    @Override
                    public void onUpImageExFail() {
                        if (isRunning) {
                            onFingerPrintListener.onFailed();
                        }
                    }

                });

                validateFingerprint.setOnGenCharExListener(new AsyncFingerprint.OnGenCharExListener() {
                    @Override
                    public void onGenCharExSuccess(int bufferId) {
                        if (isRunning) {
                            validateFingerprint.FP_UpChar();
                        }
                    }

                    @Override
                    public void onGenCharExFail() {
                        if (isRunning) {
                            onFingerPrintListener.onFailed();
                        }
                    }
                });
            }

            validateFingerprint.setOnUpCharListener(new AsyncFingerprint.OnUpCharListener() {

                @Override
                public void onUpCharSuccess(byte[] model) {
                    //onFingerPrintListener.onValidateSuccess(model,0);
                    // 显示数据库中对应的指纹ID
                    if (isRunning) {
                        Observable.create((Observable.OnSubscribe<FingerPrintBean>) subscriber -> {
                            List<FingerPrintBean> beans = AppContext.getInstance().getKjdb().findAllByWhere(FingerPrintBean.class,"fp is not null");

                            if (beans != null && !beans.isEmpty()) {
                                for (FingerPrintBean bean : beans) {
                                    mScore = FPMatch.getInstance().MatchTemplate(EncoderUtils.base64DecodeToByte(bean.getFp()), model);
                                    if (mScore > 80) {
                                        subscriber.onNext(bean);
                                        subscriber.onCompleted();
                                        return;
                                    }
                                }
                            }
                            subscriber.onError(new Exception("No Match Data"));
                            subscriber.onCompleted();
                        })
                                .subscribeOn(Schedulers.io())
                                .observeOn(AndroidSchedulers.mainThread())
                                .subscribe(new Observer<FingerPrintBean>() {
                                    @Override
                                    public void onCompleted() {

                                    }

                                    @Override
                                    public void onError(Throwable e) {
                                        onFingerPrintListener.onFailed();
                                    }

                                    @Override
                                    public void onNext(FingerPrintBean bean) {
                                        onFingerPrintListener.onValidateSuccess(bean, mScore);
                                    }
                                });
                    }
                }

                @Override
                public void onUpCharFail() {
                    if (isRunning) {
                        onFingerPrintListener.onFailed();
                    }
                }

            });
        }
    }
}